package edu.friday.service.impl;

import edu.friday.common.constant.UserConstants;
import edu.friday.common.result.TableDataInfo;
import edu.friday.model.SysRole;
import edu.friday.model.vo.SysRoleVO;
import edu.friday.repository.ISysRoleRepository;
import edu.friday.service.ISysRoleService;
import edu.friday.utils.BeanUtils;
import edu.friday.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Transactional
public class SysRoleServieImpl implements ISysRoleService {
    @Autowired
    private ISysRoleRepository iSysRoleRepository;

    @Override
    public TableDataInfo selectRoleList(SysRoleVO sysRoleVO, Pageable pageable) {
        SysRole sysRole = new SysRole();
        BeanUtils.copyPropertiesIgnoreEmpty(sysRoleVO, sysRole);
        sysRole.setDelFlag("0");
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("roleName", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("roleKey", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<SysRole> example = Example.of(sysRole, exampleMatcher);
        Page<SysRole> all = iSysRoleRepository.findAll(example, pageable);
        return TableDataInfo.success(all.toList(), all.getTotalElements());
    }

    @Override
    public String checkRoleNameUnique(SysRoleVO sysRoleVO) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleName(sysRoleVO.getRoleName());
        sysRole.setRoleId(sysRoleVO.getRoleId());
        System.out.println("检查RoleName");
        return count(sysRole);
    }

    @Override
    public String checkRoleKeyUnique(SysRoleVO sysRoleVO) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleKey(sysRoleVO.getRoleKey());
        sysRole.setRoleId(sysRoleVO.getRoleId());
        System.out.println("检查RoleKey");
        return count(sysRole);
    }

    @Override
    public boolean insertRole(SysRoleVO sysRoleVO) {
        SysRole sysRole = new SysRole();
        BeanUtils.copyPropertiesIgnoreEmpty(sysRoleVO, sysRole);
        sysRole.setDelFlag("0");
        iSysRoleRepository.save(sysRole);
        sysRoleVO.setRoleId(sysRole.getRoleId());
        insertRoleMenu(sysRoleVO);
        return null != sysRole.getRoleId();
    }

    @Override
    public int deleteRoleByIds(Long[] roleIds) {
        return iSysRoleRepository.deleteRoleByIds(roleIds);
    }

    @Override
    public int updateRole(SysRoleVO sysRoleVO) {
        Long roleId = sysRoleVO.getRoleId();
        Optional<SysRole> op = iSysRoleRepository.findById(roleId);
        if (!op.isPresent())
            return 0;
        iSysRoleRepository.deleteRoleMenuById(roleId);
        SysRole sysRole = op.get();
        BeanUtils.copyPropertiesIgnoreNull(sysRoleVO, sysRole);
        iSysRoleRepository.save(sysRole);
        return insertRoleMenu(sysRoleVO);
    }

    @Override
    public SysRole findOne(Example<SysRole> example) {
        List<SysRole> list = iSysRoleRepository.findAll(example, PageRequest.of(0, 1)).toList();
        if (list.isEmpty())
            return null;
        return list.get(0);
    }

    @Override
    public List<SysRole> selectRoleAll() {
        return iSysRoleRepository.findAll();
    }

    @Override
    public List<Long> selectRoleListByUserId(Long userId) {
        return iSysRoleRepository.selectRoleIdsByUserId(userId);
    }

    @Override
    public SysRole selectRoleById(Long roleId) {
        SysRole sysRole = new SysRole();
        sysRole.setRoleId(roleId);
        sysRole.setDelFlag("0");
        Optional<SysRole> one = iSysRoleRepository.findOne(Example.of(sysRole));
        return one.orElse(null);
    }

    @Override
    public boolean updateStatus(SysRoleVO sysRoleVO) {
        Optional<SysRole> op = iSysRoleRepository.findById(sysRoleVO.getRoleId());
        if (!op.isPresent())
            return false;
        SysRole sysRole = op.get();
        sysRole.setStatus(sysRoleVO.getStatus());
        sysRole.setUpdateBy(sysRoleVO.getUpdateBy());
        iSysRoleRepository.save(sysRole);
        return true;
    }

    @Override
    public Set<String> selectRolePermissionByUserId(Long userId) {
        List<SysRole> perms = iSysRoleRepository.selectRoleByUserId(userId);
        Set<String> permsSet = new HashSet<>();
        for (SysRole perm : perms) {
            if (StringUtils.isNotNull(perm)) {
                permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
            }
        }
        return permsSet;
    }

    private int insertRoleMenu(SysRoleVO sysRoleVO) {
        Long[] menuIds = sysRoleVO.getMenuIds();
        if (StringUtils.isNull(menuIds) || menuIds.length == 0)
            return 1;
        Long[] roleIds = new Long[menuIds.length];
        Arrays.fill(roleIds, sysRoleVO.getRoleId());
        return iSysRoleRepository.batchInsertRoleMenu(roleIds, menuIds);
    }

    /*    public String count(SysRole sysRole) {
            Example<SysRole> example = Example.of(sysRole);
            long count = iSysRoleRepository.count(example);
            if (count > 0){
                return UserConstants.NOT_UNIQUE;
            return UserConstants.UNIQUE;
        }*/
    public String count(SysRole sysRole) {
        Long roleId = StringUtils.isNull(sysRole.getRoleId()) ? -1L : sysRole.getRoleId();
        Example<SysRole> example = Example.of(sysRole);
        SysRole one = findOne(example);
//        System.out.println(one);
//        System.out.println(roleId);
        if (StringUtils.isNotNull(one) && one.getRoleId().longValue() != roleId.longValue())
            return UserConstants.NOT_UNIQUE;
        return UserConstants.UNIQUE;
    }
}
